/**
 * Copyright (c) [2025] [AGIROS] 
 * [travoddsgen] is licensed under Mulan PSL v2. 
 * You can use this software according to the terms and conditions of the Mulan PSL v2. 
 * You may obtain a copy of Mulan PSL v2 at: 
 *          http://license.coscl.org.cn/MulanPSL2 
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 
 * See the Mulan PSL v2 for more details.
 */ 

#include "SWIGJavaCMakeListsFileVisitor.h"
#include <fstream>

SWIGJavaCMakeListsFileVisitor::SWIGJavaCMakeListsFileVisitor(
    const std::string& outputDir, 
    std::string& targetName, 
    CppLangTypeSourceVisitor* typeSourceVisitor, 
    CppLangTypeSupportSourceVisitor* typeSupportSourceVisitor)
    : FileGenVisitor(outputDir, "CMakeLists.txt"), 
    typeSourceVisitor_(typeSourceVisitor), 
    typeSupportSourceVisitor_(typeSupportSourceVisitor), 
    targetName_(targetName) {
}

SWIGJavaCMakeListsFileVisitor::~SWIGJavaCMakeListsFileVisitor() {
}

void SWIGJavaCMakeListsFileVisitor::visit(SpecificationNode& node) {
    content_ += "cmake_minimum_required(VERSION 3.7)\n\n";
    content_ += "set(TARGET_NAME " + targetName_ + ")\n\n";
    content_ += "project(${TARGET_NAME})\n\n";
    content_ += "set(CMAKE_CXX_STANDARD 11)\n\n";

    // content_ += "set(travoddsz_DIR \"D:/travodds/travodds/install/cmake\")\n";
    // content_ += "set(travoddscppz_DIR \"D:/travodds/travodds_cpp/install/cmake\")\n";
    // content_ += "set(travoddsjava_DIR \"D:/travodds/travodds_java/install/cmake\")\n";
    // content_ += "list(APPEND CMAKE_MODULE_PATH \"${travoddsz_DIR}\")\n";
    // content_ += "list(APPEND CMAKE_MODULE_PATH \"${travoddscppz_DIR}\")\n";
    // content_ += "list(APPEND CMAKE_MODULE_PATH \"${travoddsjava_DIR}\")\n\n";

    content_ += "find_package(travoddscore REQUIRED)\n";
    content_ += "find_package(travoddscppz REQUIRED)\n";
    content_ += "find_package(travoddsjava REQUIRED)\n";
    content_ += "find_package(Java REQUIRED)\n";
    content_ += "find_package(JNI REQUIRED)\n\n";

    content_ += "find_package(SWIG REQUIRED)\n\n";

    content_ += "file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src/types)\n\n";

    content_ += "set(SWIG_EXECUTABLE ${SWIG_EXECUTABLE})\n";
    content_ += "set(SWIG_INTERFACE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${TARGET_NAME}.i)\n";
    content_ += "set(SWIG_OUTFILE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/jni)\n";
    content_ += "set(SWIG_OUTFILE ${SWIG_OUTFILE_DIR}/${TARGET_NAME}_wrap.cpp)\n";
    content_ += "set(SWIG_OUTPUT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/types)\n";
    content_ += "set(SWIG_FINISH_FILES ${SWIG_OUTFILE_DIR}/swig-type-finish.txt)\n";

    content_ += "set(SWIG_FLAGS -java -c++ -package types -I${travoddsz_INCLUDE_DIRS} -I${travoddscppz_INCLUDE_DIRS} -I${travoddsjava_INCLUDE_DIRS} -outdir ${SWIG_OUTPUT_DIR} -o ${SWIG_OUTFILE})\n";
    content_ += "set(SWIG_COMMAND ${SWIG_EXECUTABLE} ${SWIG_FLAGS} ${SWIG_INTERFACE_FILE})\n\n";

    content_ += "add_custom_command(\n";
    content_ += "    OUTPUT ${SWIG_OUTFILE} ${SWIG_FINISH_FILES} \n";
    content_ += "    COMMAND ${CMAKE_COMMAND} -E remove_directory ${SWIG_OUTPUT_DIR}\n";
    content_ += "    COMMAND ${CMAKE_COMMAND} -E make_directory ${SWIG_OUTPUT_DIR}\n";
    content_ += "    COMMAND ${CMAKE_COMMAND} -E remove_directory ${SWIG_OUTFILE_DIR}\n";
    content_ += "    COMMAND ${CMAKE_COMMAND} -E make_directory ${SWIG_OUTFILE_DIR}\n";
    content_ += "    COMMAND ${SWIG_COMMAND}\n";
    content_ += "    COMMAND ${CMAKE_COMMAND} -E echo \"swig finished\" > \"${SWIG_FINISH_FILES}\"\n";
    content_ += "    DEPENDS ${SWIG_INTERFACE_FILE}\n";
    content_ += "    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}\n";
    content_ += "    COMMENT \"Generating SWIG wrapper code using ${SWIG_COMMAND}\"\n";
    content_ += ")\n\n";

    content_ += "add_custom_target(swig_${TARGET_NAME} ALL DEPENDS ${SWIG_FINISH_FILES})\n\n";

    content_ += "file(GLOB_RECURSE SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)\n";
    content_ += "add_library(${TARGET_NAME}_jni SHARED ${SRC_FILES})\n";
    content_ += "target_compile_definitions(${TARGET_NAME}_jni PRIVATE ${travoddsz_DEFINITIONS})\n";
    content_ += "target_include_directories(${TARGET_NAME}_jni PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})\n";
    content_ += "target_include_directories(${TARGET_NAME}_jni PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/jni)\n";
    content_ += "target_include_directories(${TARGET_NAME}_jni PRIVATE ${JNI_INCLUDE_DIRS})\n";
    content_ += "target_include_directories(${TARGET_NAME}_jni PRIVATE ${travoddsz_INCLUDE_DIRS})\n";
    content_ += "target_include_directories(${TARGET_NAME}_jni PRIVATE ${travoddscppz_INCLUDE_DIRS})\n";
    content_ += "set_target_properties(${TARGET_NAME}_jni PROPERTIES DEBUG_POSTFIX \"d\")\n";
    content_ += "target_link_libraries(${TARGET_NAME}_jni PRIVATE debug ${travoddscppzd_LIBRARIES})\n";
    content_ += "target_link_libraries(${TARGET_NAME}_jni PRIVATE optimized ${travoddscppz_LIBRARIES})\n";
    content_ += "target_link_libraries(${TARGET_NAME}_jni PRIVATE debug ${travoddszd_LIBRARIES})\n";
    content_ += "target_link_libraries(${TARGET_NAME}_jni PRIVATE optimized ${travoddsz_LIBRARIES})\n";
    content_ += "add_dependencies(${TARGET_NAME}_jni swig_${TARGET_NAME})\n\n";

    content_ += "include(UseJava)\n";
    content_ += "file(GLOB_RECURSE java_files ${CMAKE_CURRENT_SOURCE_DIR}/src/*.java)\n";
    content_ += "set(CMAKE_JAVA_COMPILE_FLAGS \"-encoding\" \"utf-8\")\n";
    content_ += "add_jar(${TARGET_NAME} \n";
    content_ += "    SOURCES ${java_files} \n";
    content_ += "    INCLUDE_JARS ${travoddsjava_JARS}\n";
    content_ += ")\n\n";

    content_ += "if (NOT INSTALL_DIR)\n";
    content_ += "set(INSTALL_DIR \"${CMAKE_CURRENT_SOURCE_DIR}/install\")\n";
    content_ += "message(\"INSTALL_DIR is not set, using default value ${INSTALL_DIR}\")\n";
    content_ += "endif()\n\n";

    content_ += "install(TARGETS ${TARGET_NAME}_jni RUNTIME DESTINATION \"${INSTALL_DIR}/lib\" LIBRARY DESTINATION \"${INSTALL_DIR}/lib\" ARCHIVE DESTINATION \"${INSTALL_DIR}/lib\")\n";
    content_ += "install_jar(${TARGET_NAME}  DESTINATION \"${INSTALL_DIR}/lib\")\n";

    // Write content to file
    writeToFile();
}